package com.shermanzhou.nio;

import org.junit.Test;

import java.nio.ByteBuffer;

/**
 * @author zhouchaoqun
 * @date 2018/10/23 下午5:53
 */
public class BufferTest {
    /**
     * 1. allocate() 分配缓冲区
     * 2. put() 写数据
     * 3. flip() 转换读写模式
     * 4. get() 读数据
     * 5. rewind() 重读数据
     * 6. clear() 清空缓冲区，但是数据依然存在缓冲区里，只是处于"被遗忘"状态
     */
    @Test
    public void test1() {
        // 1. 分配一个指定大小的缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);
        System.out.println("-------allocate()------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        // 2. 利用 put() 存入数据
        String str = "abcde";
        buf.put(str.getBytes());
        System.out.println("-------put()------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        // 3. 切换读取模式
        buf.flip();
        System.out.println("-------flip()------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        // 4. 利用 get() 读取数据
        byte[] dest = new byte[buf.limit()];
        buf.get(dest);
        System.out.println("-------get()------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        System.out.println(new String(dest));

        // 当 position >= limit 时，再次读取缓冲区，会报 BufferUnderflowException

        // 5. 利用 rewind() 重读数据
        buf.rewind();
        System.out.println("-------rewind()------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        // 6. 利用 clear() 清空缓冲区，注意缓冲区的数据依然存在，只是出于"被遗忘"状态
        buf.clear();
        System.out.println("-------clear()------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        System.out.println((char) buf.get());
        System.out.println("-------get()------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
    }

    /**
     * 1. mark() 记录当前 position 位置
     * 2. reset() 将 position 恢复到 mark 记录的位置
     * 3. hasRemaining() position < limit
     * 4. remaining() limit-position
     */
    @Test
    public void test2() {
        ByteBuffer buf = ByteBuffer.allocate(1024);
        String str = "abcde";
        buf.put(str.getBytes());

        buf.flip();

        byte[] dest = new byte[buf.limit()];
        buf.get(dest, 0, 2);
        System.out.println(new String(dest, 0, 2));
        System.out.println(buf.position());

        buf.mark();

        buf.get(dest, 2, 2);
        System.out.println(new String(dest, 2, 2));
        System.out.println(buf.position());

        buf.reset();
        System.out.println("-------reset()------");
        System.out.println(buf.position());

        System.out.println("-------hasRemaining()------");
        if (buf.hasRemaining()) {
            System.out.println("-------remaining()------");
            System.out.println(buf.remaining());
        }
    }

    /**
     * allocateDirect() 分配直接缓冲区
     */
    @Test
    public void test3() {
        ByteBuffer buffer1 = ByteBuffer.allocate(1024);
        ByteBuffer buffer2 = ByteBuffer.allocateDirect(1024);

        System.out.println(buffer1.isDirect());
        System.out.println(buffer2.isDirect());
    }
}
